%start algoritmo
%token ALGORITMO IDENTIFICADOR INICIO FIMALGORITMO
%token VAR LETRA DIGITO MENOR_IGUAL MULTIPLICACAO CONTRABARRA ABRE_PARENTESE FECHA_PARENTESE IGUAL MAIOR_IGUAL MOD CASO PASSO MAIOR DIVISAO NAO
%token VETOR DE DIFERENTE MENOR DOIS_PONTOS INTERVALO ABRE_COLCHETE FECHA_COLCHETE ELEVADO
%token INTEIRO REAL CARACTERE LOGICO UNDERLINE ATRIBUICAO
%token PROCEDIMENTO FIMPROCEDIMENTO
%token FUNCAO ESCREVA ESCREVAL LEIA RETORNE FIMFUNCAO
%token VERDADEIRO FALSO E_CONDICIONAL
%token SE ENTAO SENAO FIMSE
%token ESCOLHA OUTROCASO FIMESCOLHA
%token PARA ATE FACA FIMPARA
%token ENQUANTO FIMENQUANTO
%token REPITA FIMREPITA
%left '-' '+' 'ou' 'xou'
%left '*' '%' 'e'
%right '^'
%%
algoritmo : 
	ALGORITMO '"'IDENTIFICADOR'"' secao_de_declaracoes INICIO comandos FIMALGORITMO
;
identificador:	IDENTIFICADOR
;			 
/*letra	: LETRA
;
arranjo	: letra arranjo 
	| digito arranjo 
	| underline arranjo
	| vazio
;*/ 
 digito	: DIGITO 
;
underline : UNDERLINE
; 
secao_de_declaracoes	:/* vazio*/|	VAR declaracao_de_variaveis declaracoes_de_subprogramas |
;
declaracao_de_variaveis	:/* vazio*/|	lista_de_variaveis : tipo_de_dado declaracao_de_variaveis 
				| lista_de_variaveis : VETOR ABRE_COLCHETE lista_de_intervalos FECHA_COLCHETE DE tipo_de_dado declaracao_de_variaveis
				
;
lista_de_variaveis	:	identificador ',' lista_de_variaveis 
				|  identificador
;
tipo_de_dado	:	INTEIRO | REAL | CARACTERE | LOGICO
;
lista_de_intervalos	:	intervalo
			| intervalo',' intervalo
;			
intervalo	:	valor_inicial INTERVALO valor_final
;
valor_inicial : const_int
;
valor_final	:	const_int
;
const_int	:	arranjo_de_digitos 
		| sinal arranjo_de_digitos
;
sinal	:	'+' | '-'
;
arranjo_de_digitos 	: digito
			| digito arranjo_de_digitos
;
declaracoes_de_subprogramas	:/* vazio*/|	def_funcao declaracoes_de_subprogramas
				|	def_procedimento declaracoes_de_subprogramas
				
;
def_procedimento	:	PROCEDIMENTO nome_do_procedimento declaracao_de_variaveis INICIO comandos FIMPROCEDIMENTO
			|	PROCEDIMENTO nome_do_procedimento ABRE_PARENTESE lista_de_parametros FECHA_PARENTESE declaracao_de_variaveis INICIO comandos FIMPROCEDIMENTO
;
nome_do_procedimento	:	identificador
;
lista_de_parametros	:	var lista_de_variaveis DOIS_PONTOS tipo_de_dado
			|	var lista_de_variaveis DOIS_PONTOS VETOR ABRE_COLCHETE lista_de_intervalos FECHA_COLCHETE DE tipo_de_dado
			|	var lista_de_variaveis DOIS_PONTOS tipo_de_dado',' lista_de_parametros
			|	var lista_de_variaveis DOIS_PONTOS VETOR ABRE_COLCHETE lista_de_intervalos FECHA_COLCHETE DE tipo_de_dado',' lista_de_parametros
;
var	:/* vazio*/|	VAR 
;
def_funcao:/* vazio*/|FUNCAO nome_da_funcao DOIS_PONTOS tipo_de_dado declaracao_de_variaveis INICIO comandos_para_funcao FIMFUNCAO def_funcao
	  |FUNCAO nome_da_funcao ABRE_PARENTESE lista_de_parametros FECHA_PARENTESE DOIS_PONTOS tipo_de_dado declaracao_de_variaveis INICIO comandos_para_funcao FIMFUNCAO def_funcao
	  
;
nome_da_funcao	:	identificador
;
/* Aqui termina a seção de declarações ************************************************************************ */

/* ******************* Definição da seção de comandos *********************** */

comandos	:	/* vazio*/|atribuicao comandos 
		|	escreva comandos
		|	leia comandos 
		|	desvio_condicional comandos
		|	selecao_multipla comandos
		|	est_repeticao comandos
		|	chamada_de_procedimento comandos
;
 
atribuicao	:	identificador ATRIBUICAO expressao
;
			

expressao : | expressao '<' expressao
| expressao '=' expressao
| expressao '>' expressao
| expressao '+' expressao
| expressao '-' expressao
| expressao '*' expressao
| expressao '/' expressao
| expressao '^' expressao
| '(' expressao ')'
;
/*		
expr_precedencia_3	:	expr_precedencia_3 op_aditivo expr_precedencia_2
			|	expr_precedencia_2
;

expr_precedencia_2	:	expr_precedencia_2 op_multiplicativo expr_precedencia_1
			|	expr_precedencia_1
;

expr_precedencia_1	:	fator ELEVADO expr_precedencia_1 
			|fator
;
*/
/*fator	:	IDENTIFICADOR
	|	ABRE_PARENTESE expressao FECHA_PARENTESE 
	|	constante
	|	sinal IDENTIFICADOR
	|	chamada_de_funcao
	|	NAO fator
;
*/
/*constante	:	const_int
		|	const_real 
		|	'"'cadeia_de_caracteres'"' 
		|	VERDADEIRO 
		| 	FALSO
;
*/
const_real	:	arranjo_de_digitos '.' arranjo_de_digitos 
		|	sinal arranjo_de_digitos '.' arranjo_de_digitos
;
			
cadeia_de_caracteres	:	/* vazio*/| caracter cadeia_de_caracteres
;

caracter	: digito
		| IDENTIFICADOR
		/*| codigo_asc_valido */
;


chamada_de_funcao	:	nome_da_funcao | nome_da_funcao ABRE_PARENTESE lista_de_variaveis FECHA_PARENTESE
;
op_relacional	:	MENOR | MAIOR | IGUAL | MENOR_IGUAL | MAIOR_IGUAL | DIFERENTE
;

op_aditivo	:	'+' | '-' | 'ou' | 'xou'
;

op_multiplicativo	:	MULTIPLICACAO | CONTRABARRA | DIVISAO| MOD | E_CONDICIONAL
;

/* Aqui termina a definição de <atribuicao> e inicia a definicao de <escreva> */

escreva	:	ESCREVA ABRE_PARENTESE parametros_escreva FECHA_PARENTESE | ESCREVAL ABRE_PARENTESE parametros_escreva FECHA_PARENTESE
;

parametros_escreva	:	expressao formatador
			|	expressao formatador',' parametros_escreva
;
formatador	:	/* vazio*/|':' const_int 
		|	':' identificador
		|	':' const_int ':' const_int
		|	':' identificador ':' identificador 
;

/* Termino da definição de <escreva> */

/* Definição de <leitura> */

leia	:	LEIA ABRE_PARENTESE lista_de_variaveis FECHA_PARENTESE
;

/* Definição de <desvio_condicional> */

desvio_condicional	:	casada | livre
;

casada	:	SE expressao ENTAO casada SENAO casada FIMSE
	| comandos
;

livre	:	SE expressao ENTAO desvio_condicional FIMSE 
	|	SE expressao ENTAO casada SENAO livre FIMSE
;		
/* Término da definição de <desvio_condicional> */

/********************* Definição de seleção múltipla **************************/

selecao_multipla	:	ESCOLHA expressao /*casos*/ OUTROCASO comandos FIMESCOLHA
;
/*casos	:	CASO lista_de_expressoes comandos 
	|	CASO lista_de_expressoes comandos casos
;
*/
lista_de_expressoes	:	expressao
			|	expressao',' lista_de_expressoes
;

/***************** Definição das três estruturas de repetição *****************/

est_repeticao	:	para_faca
		| enquanto_faca
		| repita_ate
;
 
para_faca	:	PARA identificador DE valor_inicial ATE valor_limite FACA comandos FIMPARA
		|	PARA identificador DE valor_inicial ATE valor_limite PASSO incremento FACA comandos FIMPARA
;
valor_limite :	const_int
;

incremento	:	expressao
;

enquanto_faca	:	ENQUANTO expressao FACA comandos FIMENQUANTO
;

repita_ate	:	REPITA comandos ATE expressao
		|	REPITA comandos FIMREPITA
;

/* ******************* Definição de chamada de procedimento ***************** */

chamada_de_procedimento	:	nome_do_procedimento
			|	nome_do_procedimento ABRE_PARENTESE lista_de_variaveis FECHA_PARENTESE
;


/* Término da seção de comandos ****************************************************************************** */


/* Definição da seção de comandos de para função (Inclui o comando retorne) ********************************** */

comandos_para_funcao	:	/* vazio*/|desvio comandos_para_funcao
			|	selecao comandos_para_funcao
			|	repeticao comandos_para_funcao
			|	atribuicao comandos_para_funcao
			|	escreva comandos_para_funcao 
			|	leia comandos_para_funcao 
			|	RETORNE expressao
			|	chamada_de_procedimento comandos_para_funcao
			
;
/* Definição de <desvio> condicional para funções */

desvio	:	casada_f | livre_f
;

casada_f	:	SE expressao ENTAO casada_f SENAO casada_f FIMSE
			| comandos_para_funcao
;
livre_f	:	SE expressao ENTAO desvio FIMSE |
			SE expressao ENTAO casada_f SENAO livre_f FIMSE
;		
/* Término da definição de <desvio> para funções */

/* Definição de seleção múltipla para funções */

selecao	:	ESCOLHA expressao /*casos_f*/ OUTROCASO comandos_para_funcao FIMESCOLHA
;

/*casos_f	:	CASO lista_de_expressoes comandos_para_funcao |
			CASO lista_de_expressoes comandos_para_funcao casos_f
;
*/
/* Definição das três estruturas de repetição para funções */

repeticao	:	para_f | enquanto_f | repita_f
; 
para_f	:	PARA identificador DE valor_inicial ATE valor_limite FACA comandos_para_funcao	FIMPARA
		|PARA identificador DE valor_inicial ATE valor_limite PASSO incremento FACA comandos_para_funcao FIMPARA
;
enquanto_f	:	ENQUANTO expressao FACA comandos_para_funcao FIMENQUANTO
;
repita_f	:	REPITA comandos_para_funcao ATE expressao |
			REPITA comandos_para_funcao FIMREPITA
;
%%
#include <stdio.h>
main( int argc, char *argv[] )
{ 

  extern FILE *yyin;
  yyin = fopen(argv[1], "r" );
  yyparse ();
}

yyerror (char *s) /* Called by yyparse on error */
{ 
  printf ("%s\n", s);
}
